package com.codemonkey.lq.qd.db.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.codemonkey.lq.qd.db.ICoreDao;
import com.codemonkey.lq.qd.db.support.PageParameter;

/**
 * TODO 每次Service执行过程中, 如果字段sqlSessionFactory未变,MyBatisDaoImpl就使用同一个
 * 后期可能在执行方法中多加入一个SqlSessionFactory类型的参数,然后Service负责SqlSession的获取
 * @author LQ
 *
 */
public class MyBatisDaoImpl implements ICoreDao {

	private static Logger log = LoggerFactory.getLogger(MyBatisDaoImpl.class);
//
//	private SqlSessionFactory sqlSessionFactory;
//
//	public MyBatisDaoImpl(SqlSessionFactory sqlSessionFactory) {
//		super();
//		this.sqlSessionFactory = sqlSessionFactory;
//	}
	
	private static final MyBatisDaoImpl INSTANCE = new MyBatisDaoImpl();
	
	public static MyBatisDaoImpl getDefaultInstance(){
		return INSTANCE;
	}

	private MyBatisDaoImpl(){
		
	}
	
	@Override
	public int deleteWithoutCloseSqlSession(SqlSession session,String sqlId, Object param) throws Exception {
		try{
			String sql = SqlUtil.showSql(session, sqlId, param);
			debugLog(sqlId,"execute sql:" + sql,param);
			int cnt = session.delete(sqlId, param);
			debugLog("success delete ["+cnt+"] items");
			return cnt;
		}catch(Exception e){
			throw e;
		}/* finally{
			session.close();
			session = null;
		}*/
		
	}

	@Override
	public int insertWithoutCloseSqlSession(SqlSession session,String sqlId, Object param) throws Exception {
		try {
			String sql = SqlUtil.showSql(session, sqlId, param);
			debugLog(sqlId, "execute sql:" + sql, param);
			int cnt = session.insert(sqlId, param);
			debugLog("success insert [" + cnt + "] items");
			return cnt;
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}/* finally {
			session.close();
			session = null;
		}*/
	}

	@Override
	public List selectListWithoutCloseSqlSession(SqlSession session,String sqlId, Object param) throws Exception {
		try {
			String sql = SqlUtil.showSql(session, sqlId, param);
			debugLog(sqlId, "execute sql:" + sql, param);
			List list = session.selectList(sqlId, param);
			if (list != null) {
				return list;
			}
			return new ArrayList();
		} catch (Exception e) {
			throw e;
		} /*finally {
			session.close();
			session = null;
		}*/
	}

	@Override
	public List selectListByPageWithoutCloseSqlSession(SqlSession session,String sqlId, Object param, PageParameter pageParameter)
			throws Exception {
		try {
			String sql = SqlUtil.showSql(session, sqlId, param);
			debugLog(sqlId, "execute sql:" + sql, param);

			//TODO 分页
//			String pagerExecutor = XMLServiceConfig.getDefaultValue("pagerExecutor");
//			PagerExecutor executor = (PagerExecutor) Class.forName(pagerExecutor).newInstance();
//			List resultList = executor.limit(sql, session, pageParameter);
			return null;
		} catch (Exception e) {
			throw e;
		}/* finally {
			session.close();
			session = null;
		}*/
	}

	@Override
	public Map selectOneWithoutCloseSqlSession(SqlSession session,String sqlId, Object param) throws Exception {
		try {
			String sql = SqlUtil.showSql(session, sqlId, param);
			debugLog(sqlId, "execute sql:" + sql, param);

			Object obj = session.selectOne(sqlId, param);
			if (obj != null) {
				Map resultMap = (Map) obj;
				return resultMap;
			}
		} catch (Exception e) {
			throw e;
		} /*finally {
			session.close();
			session = null;
		}*/

		return null;
	}

	@Override
	public int updateWithoutCloseSqlSession(SqlSession session,String sqlId, Object param) throws Exception {
		try {
			String sql = SqlUtil.showSql(session, sqlId, param);
			debugLog(sqlId, "execute sql:" + sql, param);
			int cnt = session.update(sqlId, param);
			return cnt;
		} catch (Exception e) {
			throw e;
		}/* finally {
			session.close();
			session = null;
		}*/

	}

	@Override
	public Object selectObjectWithoutCloseSqlSession(SqlSession session,String sqlId, Object param) throws Exception {
		try {
			String sql = SqlUtil.showSql(session, sqlId, param);
			debugLog(sqlId, "execute sql:" + sql, param);

			Object obj = session.selectOne(sqlId, param);
			if (obj != null) {
				return obj;
			}

			return null;
		} catch (Exception e) {
			throw e;
		} /*finally {
			session.close();
			session = null;
		}*/

	}

	private void debugLog(String logInfo) {
		outputSeperateLine();
		log.debug(logInfo);
		outputSeperateLine();
	}

	private void debugLog(String sqlId, String logInfo, Object param) {
		outputSeperateLine();
		//System.out.println("input params is -- "+ JsonUtil.stringify(param));
		System.out.println("\\\\\\ mybatis sqlId is ' " + sqlId + " ' ///");
		log.debug(logInfo);
		outputSeperateLine();
	}

	private void outputSeperateLine() {
		// log.debug(Strings.repeat("**", 30));
		System.out.println("**************************************************************");
	}
	
	private static class SqlUtil {
		static String showSql(SqlSession session, String sqlId, Object param){
			String sql = session.getConfiguration().getMappedStatement(sqlId).getBoundSql(param).getSql();		
			// sql.replaceAll("\\s*", "");
			return sql;
		}
	}
}
